﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Marbles.Core.Content.Users;
using Marbles.Core.Authentication.Generic;
using Marbles.Core.Authentication.OpenID;
using Marbles.Core.Connectors;

namespace Marbles.Core.Authentication
{
    /// <summary>
    /// Base AuthenticationProvider. All calls should be made through this class
    /// </summary>
    public abstract class AuthenticationProvider
    {

        /// <summary>
        /// Returns the Current user Token
        /// </summary>
        public IToken CurrentToken
        {
            get
            {
                return GetCurrentToken();
            }
        }

        /// <summary>
        /// Returns TRUE if authenticated
        /// </summary>
        public bool IsAuthenticated
        {
            get
            {
                IToken token = CurrentToken;
                if (token == null) { return false; }
                return token.Success;
            }
        }

        public abstract string Provider { get; }
        public abstract bool RequiresPassword { get; }
        public abstract bool Login(string username, string password);
        public abstract IToken Authenticate();
        public abstract IToken GetToken(string username, string password);
        public static User GetUser(string username, string siteid)
        {
            return User.GetByUsername(username, siteid);
        }

        /// <summary>
        /// Returns the created Root User for the specified Site
        /// </summary>
        /// <param name="siteid">Site Id to query</param>
        /// <returns></returns>
        public static User GetRootUser(string siteid)
        {
            return User.GetRootUser(siteid);
        }

        /// <summary>
        /// Create a new "Root" user for the specified Site
        /// </summary>
        /// <param name="siteId">Site to create user for</param>
        /// <param name="username">Username to use</param>
        /// <param name="password">Password to use</param>
        public static void CreateRootUser(string siteId, string username, string password)
        {
            DataConnection dbc = new DataConnection();
            User u = User.CreateNew(siteId);
            u.Username = username;
            u.Password = password;
            u.Fullname = "Root";
            u.Groups.Add(4);
            u.Enabled = true;
            u.Insert();
        }


        /// <summary>
        /// Copy the Root user from one site to another
        /// </summary>
        /// <param name="oldSiteId">Source SiteId</param>
        /// <param name="newSiteId">Destination SiteId</param>
        public static void CopyRootUser(string oldSiteId, string newSiteId)
        {
            User root = GetRootUser(oldSiteId);
            if (root != null)
            {
                root.CopyToSite(newSiteId);
                root.Insert();
            }
        }

        /// <summary>
        /// Logout the Current User and abandon the current session.
        /// </summary>
        /// <returns>Returns True if successful.</returns>
        public bool Logout()
        {
            HttpContext.Current.Session["AuthenticationTicket"] = null;
            HttpContext.Current.Session.Remove("AuthenticationTicket");
            HttpContext.Current.Session.Abandon();
            HttpContext.Current.Session.RemoveAll();
            return true;
        }


        /// <summary>
        /// Create an Instance of AuthenticationProvider based on the configured provider.
        /// </summary>
        /// <returns>new Instance of AuthenticationProvider</returns>
        public static AuthenticationProvider CreateProviderInstance()
        {
            AuthenticationProvider value = null;
            string providerName = Settings.SettingsManager.AuthenticationProvider;
            switch (providerName.ToLower())
            {
                case "openidprovider":
                case "openid":
                    value = new OpenIdProvider();
                    break;
                case "genericprovider":
                case "generic":
                default:
                    value = new GenericProvider();
                    break;
            }

            return value;
        }

        protected virtual IToken GetCurrentToken()
        {
            IToken token = null;

            if (HttpContext.Current.Session != null)
            {
                if (HttpContext.Current.Session["AuthenticationTicket"] != null)
                {
                    token = HttpContext.Current.Session["AuthenticationTicket"] as IToken;
                }
            }

            return token;
        }

        protected virtual void SetCurrentToken(IToken Token)
        {
            if (HttpContext.Current.Session == null) { return; }
            HttpContext.Current.Session["AuthenticationTicket"] = Token;
        }


    }
}